﻿using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using Mehdime.Entity;
using WikeSoft.Core;
using WikeSoft.Core.Exception;
using WikeSoft.Core.Extension;
 
using WikeSoft.Enterprise.Entities;
using WikeSoft.Enterprise.Interfaces.Sys;
using WikeSoft.Enterprise.Models;
using WikeSoft.Enterprise.Models.Filters.Sys;
using WikeSoft.Enterprise.Models.Sys;

namespace WikeSoft.Enterprise.AppServices.Sys
{
    public class DepartmentService:IDepartmentService
    {
        private readonly IMapper _mapper;
        private readonly IDbContextScopeFactory _dbContextScopeFactory;
        public DepartmentService(IMapper mapper, IDbContextScopeFactory dbContextScopeFactory)
        {
            _mapper = mapper;
            _dbContextScopeFactory = dbContextScopeFactory;
        }

        /// <summary>
        /// 根据父节点查询列表
        /// </summary>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public IList<ZTreeModel> GetByParentId(string parentId)
        {
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var query = db.SysDepartments.Where(x=>x.IsDelete==false);
                query = parentId == string.Empty
                    ? query.Where(x => x.ParentId == string.Empty)
                    : query.Where(x => x.ParentId == parentId);
                return query.OrderBy(c=>c.PathCode).Select(x => new ZTreeModel
                {
                    id = x.Id,
                    name = x.DepartmentName,
                    isParent = db.SysDepartments.Any(p => p.ParentId == x.Id && p.IsDelete==false)
                }).ToList();
            }
        }

        public DepartmentEditModel Find(string Id)
        {
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var entity = db.SysDepartments.Load(Id);
                var page = _mapper.Map<SysDepartment, DepartmentEditModel>(entity);
                if (entity.ParentId != string.Empty)
                {
                    var parent = db.SysDepartments.Load(entity.ParentId);
                    page.ParentName = parent.DepartmentName;
                }
                return page;
            }
        }

        public bool Add(DepartmentAddModel model)
        {
            using (var scope = _dbContextScopeFactory.Create())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var entity = _mapper.Map<DepartmentAddModel, SysDepartment>(model);
               
                //设置页面的路劲码
                entity.PathCode = GetPathCode(db, model.ParentId);
                db.SysDepartments.Add(entity);
                return scope.SaveChanges() > 0;
            }
        }

        public bool Delete(string id)
        {
           
            
                using (var scope = _dbContextScopeFactory.Create())
                {
                    var db = scope.DbContexts.Get<WikeDbContext>();

                    var count = db.SysDepartments.Count(c => c.ParentId == id);
                    if (count > 0)
                    {
                        throw new TipInfoException("请先删除下级数据");
                    }
                    var delete = db.SysDepartments.FirstOrDefault(c => c.Id == id);

                    if (delete != null)
                    {
                        if (delete.SysUsers.Count(x => x.IsDelete == false) > 0)
                        {
                            throw new TipInfoException("该部门存在用户，禁止删除");
                        }
                        delete.IsDelete = true;

                    }
                    

                    scope.SaveChanges();
                }


            return true;


        }

        public bool Edit(DepartmentEditModel model)
        {
            using (var scope = _dbContextScopeFactory.Create())
            {
                
                var db = scope.DbContexts.Get<WikeDbContext>();
                var entity = db.SysDepartments.Load(model.Id);
                var subs = db.SysDepartments.Where(c => c.PathCode.StartsWith(entity.PathCode) && c.Id != model.Id).ToList();
                var subIds = subs.Select(c => c.Id).ToList();
                if (subIds.Contains(model.ParentId))
                {
                    throw new TipInfoException("上级部门不能为当前部门的下级部门");
                }
                if (model.Id == model.ParentId)
                {
                    throw new TipInfoException("上级部门不能为当前部门");
                }
                var oldId = entity.ParentId;
                var newId = model.ParentId;
                var oldPathCode = entity.PathCode;
                _mapper.Map(model, entity);

                 
                if (!oldId.Equals(newId))
                {
                    var pathCode = GetPathCode(db, newId);

                    subs.ForEach(c =>
                    {
                        c.PathCode = c.PathCode.Replace(oldPathCode, pathCode);
                    });

                    entity.PathCode = pathCode;
                }
                scope.SaveChanges();

                //不执行存储过程
                //if (newId != oldId)
                //{
                //    var row = db.ProUpdateDepartmentPathCode(entity.Id, entity.ParentId);
                //}

                return true;
            }
        }

        public PagedResult<DepartmentModel> Query(DepartmentFilter filters)
        {
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var query = db.SysDepartments.Where(x=>x.IsDelete ==false);
                if (filters.keywords.IsNotBlank())
                {
                    query = query.Where(x => x.DepartmentName.Contains(filters.keywords));
                }
                return query.OrderByCustom(filters.sidx, filters.sord)
                    .Select(x => new DepartmentModel
                    {
                        Id = x.Id,
                        ParentId = x.ParentId,
                        DepartmentName = x.DepartmentName,
                        DepartmentCode = x.DepartmentCode,
                        Remark = x.Remark
                       
                    }).Paging(filters.page, filters.rows);
            }
        }

        public List<DepartmentModel> GetList()
        {
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var query = db.SysDepartments.AsQueryable();

                return query
                    .Select(x => new DepartmentModel
                    {
                        Id = x.Id,
                        ParentId = x.ParentId,
                        DepartmentName = x.DepartmentName,
                        DepartmentCode = x.DepartmentCode,
                        Remark = x.Remark

                    }).ToList();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="includeSelf"></param>
        /// <returns></returns>
        public List<DepartmentModel> GetParentDepartmentByUserId(string userId, bool includeSelf = true)
        {
            List <DepartmentModel> list = new List<DepartmentModel>();
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                string departmentId;
                var db = scope.DbContexts.Get<WikeDbContext>();
                var user = db.SysUsers.Find(userId);
                if (user == null)
                {
                    throw new Exception(string.Format("找不到当前用户，userId={0}", userId));
                }
                if (user.DepartmentId == null)
                {
                    throw new Exception(string.Format("用户未设置部门，userId={0}",userId));
                }
              
                if (includeSelf)
                {
                    list.Add(_mapper.Map<SysDepartment, DepartmentModel>(user.SysDepartment));
                }
                departmentId = user.SysDepartment.ParentId;
                while (true)
                {
                    var department = db.SysDepartments.Find(departmentId);
                    if (department == null)
                    {
                        throw new Exception(string.Format("找不到部门，departmentId={0}", departmentId));
                    }
                    list.Add(_mapper.Map<SysDepartment, DepartmentModel>(department));
                    if (string.IsNullOrEmpty(department.ParentId))
                    {
                        break;
                    }
                    departmentId = department.ParentId;
                } 
            }

            return list;
        }

        public string GetDepartmentName(string userId, bool includeParent)
        {
            
            List<SysDepartment> list = new List<SysDepartment>();
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var user = db.SysUsers.Find(userId);
                if (user != null)
                {
                    var department = user.SysDepartment;
                    list.Add(department);
                    if (includeParent)
                    {
                        if (department.ParentId != string.Empty)
                        {
                            var partDepartment = db.SysDepartments.Find(department.ParentId);
                            list.Add(partDepartment);
                        }
                    }
                 
                   
                }
                return list.OrderBy(x => x.PathCode).Select(x => x.DepartmentName).Join("-");
            }
           
        }

        public List<DepartmentModel> GetMyDepartmentList(string userId)
        {

          
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var user = db.SysUsers.Load(userId);
                var data = db.SysDepartments.Where(c => c.PathCode.StartsWith(user.SysDepartment.PathCode)).Select(item=> new DepartmentModel()
                {
                    Id = item.Id,
                    DepartmentName = item.DepartmentName,
                    DepartmentCode = item.DepartmentCode,
                    ParentId = item.ParentId,
                    //ParentName = item.ParentName,
                    Remark = item.Remark
                   
                }).ToList();
                return data;
            }
        }

        /// <summary>
        /// 获取路径码
        /// </summary>
        /// <param name="db"></param>
        /// <param name="parentPageId"></param>
        /// <returns></returns>
        private string GetPathCode(IWikeDbContext db, string parentPageId)
        {
            //顶级页面
            List<string> existCodes;
            var parentPathCode = string.Empty;
            if (parentPageId.IsBlank())
            {
                existCodes = db.SysDepartments.Where(x => x.ParentId == null || x.ParentId == string.Empty)
                    .Select(x => x.PathCode).ToList();
            }
            else
            {
                var page = db.SysDepartments.Load(parentPageId);
                parentPathCode = page.PathCode;

                existCodes = db.SysDepartments.Where(x => x.ParentId == parentPageId)
                    .Select(x => x.PathCode).ToList()
                    .Select(x => x.Substring(page.PathCode.Length, 2)).ToList();
            }
            var pathCode = CodeTable.SysPathCodes
                    .OrderBy(x => x)
                    .First(x => !existCodes.Contains(x));
            return parentPathCode + pathCode;
        }
    }


}
